import com.mytest.provider.rll.DistributedLock;
import com.mytest.provider.rll.RedisDistributedLock;
import com.mytest.provider.rll.RllApplication;
import com.mytest.provider.rll.config.redis.RedisConfig;
import jdk.nashorn.internal.runtime.regexp.joni.Config;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.redisson.Redisson;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit4.SpringRunner;

import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import static java.util.concurrent.TimeUnit.SECONDS;

/**
 * @Author: llq
 * @Date: 2020/5/18
 */
@RunWith(SpringRunner.class)
@SpringBootTest(classes = RllApplication.class)
@TestPropertySource("classpath:application-dev.yml")
public class ce {
    private static Integer Inventory = 1001;

    @Autowired
    static DistributedLock distributedLock;

    /*@Autowired
    RedisDistributedLock redisDistributedLock;*/

    @Autowired
    RedisTemplate redisTemplate;

    @Autowired
    Redisson redisson;

    @Test
    public void a(){
        //创建了很多个线程去扣减库存inventory，不出意外的库存扣减顺序变了，最终的结果也是不对的。
        LinkedBlockingQueue queue = new LinkedBlockingQueue<>();
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(Inventory, Inventory, 10L, SECONDS, queue);
        long start = System.currentTimeMillis();

        /*for (int i = 0; i <= 1000; i++) {
            threadPoolExecutor.execute(() -> {
                try {
                    distributedLock.lock("redis_l",1000 , 10, 1000);
                    Inventory--;
                    System.out.println("11111111111111:"+Inventory);
                }finally {
                    distributedLock.releaseLock("redis_l");
                }
            });
        }*/
        /*boolean redis_l = redisDistributedLock.lock("redis_l", 1000, 10, 1000);
        System.out.println("x:"+redis_l);
        Inventory--;
        System.out.println("11111111111111:"+Inventory);
        redisDistributedLock.releaseLock("redis_l");*/

        //多个线程过来，只有一个线程能拿到锁
        //先拿到这把锁的对象
        RLock rdislock = redisson.getLock("key");
        //往redis里面设置了这样一把锁，并且设置了超时的时间为30s
        rdislock.lock(30, TimeUnit.SECONDS);

        for (int i = 0; i <= 1000; i++) {
            threadPoolExecutor.execute(() -> {

                RedisDistributedLock redisDistributedLock = new RedisDistributedLock(redisTemplate);

                boolean redis_l = redisDistributedLock.lock("redis_l", 1000, 10, 1000);
                System.out.println("x:"+redis_l);
                Inventory--;
                System.out.println("11111111111111:"+Inventory);
                redisDistributedLock.releaseLock("redis_l");
            });
        }

        long end = System.currentTimeMillis();
        System.out.println("执行线程数 ：" + 1000 + ",总耗时：" + (end - start) + ",库存数:" + Inventory);
    }
}
